﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Xml;

using EdgeStatz.ESSystems.Objects;

namespace EdgeStatz.ModelEngine.DatabaseTools
{
    class DEXMLReader
    {
        #region Instance Variables

        private string xmlFilePath = null;

        private List<TableData> dataTableArray = new List<TableData> { };

        #endregion

        #region Properties
        public TableData[] DataTableArray
        {
            get { return dataTableArray.ToArray(); }
        }
        public string XmlFilePath
        {
            get { return xmlFilePath; }
        }
        #endregion

        #region Constructors

        public DEXMLReader(string path) 
        { 
            using (XmlTextReader textReader = new XmlTextReader(path))
                xmlFilePath = textReader.BaseURI;
            Init();
        }
        #endregion

        #region Table Methods
        public bool DataTableExists(string name)
        {
            foreach (TableData table in this.DataTableArray)
            {
                if (table.Name.Equals(name))
                    return true;
            }
            return false;
        }
        public TableData GetTable(string name)
        {
            foreach (TableData table in this.DataTableArray)
            {
                if (table.Name.Equals(name))
                    return table;
            }
            return null;
        }
        public TableData GetTable(int index)
        {
            if (index >= dataTableArray.Count || index < 0)
                return null; // index out of bounds throw new Exception("Table index out of bounds.");
            return (TableData)dataTableArray[index];
        }
        #endregion

        private void Init() 
        {
            if (XmlFilePath == null)
                throw new NullReferenceException("Error: Model file not selected.");

             XmlDocument myXmlDocument = new XmlDocument();
            myXmlDocument.Load(XmlFilePath);

            XmlNode rootNode;
            rootNode = myXmlDocument.DocumentElement;
            if (!rootNode.Name.Trim().ToUpper().Equals("DATA"))
                throw new Exception("Error: Model file is corrupted.");

            foreach (XmlNode node1 in rootNode.ChildNodes)
            {
                if (node1.Name.ToUpper() == "TABLE")
                {
                    TableData nexttable = new TableData(node1.Attributes["Name"] == null ? null : node1.Attributes["Name"].Value);
                    foreach (XmlNode node2 in node1.ChildNodes)
                    {
                        switch (node2.Name.ToUpper())
                        {
                            case "COLUMN":
                                ColumnType type;
                                switch (node2.Attributes["Type"].Value.ToUpper())
                                {
                                    case "BIT":
                                        type = ColumnType.Bit;
                                        break;
                                    case "DATETIME":
                                        type = ColumnType.Datetime;
                                        break;
                                    case "FLOAT":
                                        type = ColumnType.Float;
                                        break;
                                    case "GUID":
                                        type = ColumnType.GUID;
                                        break;
                                    case "INT":
                                        type = ColumnType.Int;
                                        break;
                                    case "VARCHAR":
                                        type = ColumnType.Varchar;
                                        break;
                                    default:
                                        throw new NullReferenceException("Column type not found");
                                }
                                nexttable.AddColumnDefinition(node2.Attributes["Name"] == null ? null : node2.Attributes["Name"].Value, type);
                                break;
                            case "DATAROW":
                                RowData nextrow = new RowData();
                                int i = 0;
                                foreach (XmlNode node4 in node2.ChildNodes)
                                {
                                    if (node4.Name.ToUpper() == "VALUE")
                                    {
                                        if (node4.Attributes["Null"] != null && node4.Attributes["Null"].Value.Trim().ToUpper().Equals("TRUE"))
                                            nextrow.Insert(DBNull.Value);
                                        else
                                            nextrow.Insert(node4.InnerText, nexttable.GetColumnType(i));
                                        i++;
                                    }                                    
                                }
                                nexttable.AddRow(nextrow);
                                break;
                        }                           
                    }
                    dataTableArray.Add(nexttable);
                }
            }
        }
    }
}
